package com.dashu.park.service;

import com.dashu.base.enums.ReplRyCode;
import com.dashu.base.utils.CopyUtil;
import com.dashu.base.utils.UIDUtil;
import com.dashu.base.utils.VerificationUtil;
import com.dashu.park.dto.company.EnterpriseDTO;
import com.dashu.park.dto.company.EnterpriseDepartmentDTO;
import com.dashu.park.handler.VerificationException;
import com.dashu.park.model.EnterpriseDepartment;
import com.dashu.park.model.QEnterpriseDepartment;
import com.dashu.park.result.PageEnty;
import com.dashu.park.vo.UpdateEntityVO;
import com.dashu.park.vo.company.EnterpriseDepartmentVO;
import com.google.common.collect.Lists;
import com.querydsl.core.BooleanBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.FlushModeType;
import javax.transaction.Transactional;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class EnterpriseDepartmentService extends DataService {

    @Autowired
    private EnterpriseService enterpriseService;

    @Transactional
    public EnterpriseDepartmentDTO add(EnterpriseDepartmentVO enterpriseDepartmentVO) {
        EnterpriseDepartment enterpriseDepartment = CopyUtil.copyEnty(enterpriseDepartmentVO, EnterpriseDepartment.class);
        try {
            long userId = Long.parseLong(VerificationUtil.getUserId());
            enterpriseDepartment.setId(UIDUtil.nextId());
            enterpriseDepartment.setCreateUser(userId);
            enterpriseDepartment.setCreateTime(System.currentTimeMillis());
            entityManager.persist(enterpriseDepartment);
//            entityManager.flush();
            entityManager.setFlushMode(FlushModeType.AUTO);
        } catch (Exception e) {
            e.printStackTrace();
            throw new VerificationException(ReplRyCode.DATA_NOT_INVALID, ReplRyCode.DATA_NOT_INVALID.getMessage());
        }
        EnterpriseDepartmentDTO enterpriseDepartmentDTO = CopyUtil.copyEnty(enterpriseDepartment, EnterpriseDepartmentDTO.class);
        return enterpriseDepartmentDTO;

    }

    @Transactional
    public boolean deleteByEnterpriseDepartmentId(long enterpriseDepartmentId) {
        QEnterpriseDepartment qEnterpriseDepartment = QEnterpriseDepartment.enterpriseDepartment;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterpriseDepartment.id.eq(enterpriseDepartmentId));
        EnterpriseDepartment enterpriseDepartment = queryFactory
                .select(qEnterpriseDepartment)
                .from(qEnterpriseDepartment)
                .where(booleanBuilder.getValue()).fetchOne();
        if (enterpriseDepartment == null)
            throw new VerificationException(ReplRyCode.COMPANY_NOT_DATA, ReplRyCode.COMPANY_NOT_DATA.getMessage());
        entityManager.remove(enterpriseDepartment);
//            entityManager.flush();
        entityManager.setFlushMode(FlushModeType.AUTO);
        return true;
    }

    @Transactional
    public EnterpriseDepartmentDTO updataByEnterpriseDepartmentId(UpdateEntityVO<EnterpriseDepartmentVO> updateCompanyDepartmentVO) throws Exception {
        QEnterpriseDepartment qEnterpriseDepartment = QEnterpriseDepartment.enterpriseDepartment;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        EnterpriseDepartmentVO companyDepartmentVO = updateCompanyDepartmentVO.getEntityVO();
        EnterpriseDepartmentDTO companyDepartmentDTO = existByCompanyDepartmentName(companyDepartmentVO.getEnterpriseName(), companyDepartmentVO.getEnterpriseId());
        if (companyDepartmentDTO != null) {
            throw new VerificationException(ReplRyCode.EXIST_COMPANY_DEPARTMENT, ReplRyCode.EXIST_COMPANY_DEPARTMENT.getMessage());
        }
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterpriseDepartment.id.eq(updateCompanyDepartmentVO.getId()));
        EnterpriseDepartment enterpriseDepartment;
        try {
            enterpriseDepartment = queryFactory
                    .select(qEnterpriseDepartment)
                    .from(qEnterpriseDepartment)
                    .where(booleanBuilder.getValue()).fetchOne();
            if (enterpriseDepartment == null)
                throw new VerificationException(ReplRyCode.COMPANY_NOT_DATA, ReplRyCode.COMPANY_NOT_DATA.getMessage());
            enterpriseDepartment.setUpdateUser(userId);
            enterpriseDepartment.setUpdateTime(new Date().getTime());
            if (companyDepartmentVO.getEnterpriseName() != null)
                enterpriseDepartment.setDepartmentName(companyDepartmentVO.getEnterpriseName());
            if (companyDepartmentVO.getEnterpriseId() != 0)
                enterpriseDepartment.setEnterpriseId(companyDepartmentVO.getEnterpriseId());
            enterpriseDepartment = entityManager.merge(enterpriseDepartment);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
//        entityManager.flush();
        entityManager.setFlushMode(FlushModeType.AUTO);
        EnterpriseDepartmentDTO EnterpriseDepartmentDTO = CopyUtil.copyEnty(enterpriseDepartment, EnterpriseDepartmentDTO.class);
        return EnterpriseDepartmentDTO;

    }

    public List<EnterpriseDepartmentDTO> findByCreteUser(PageEnty<Long> baseVo) {
        QEnterpriseDepartment qEnterpriseDepartment = QEnterpriseDepartment.enterpriseDepartment;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterpriseDepartment.createUser.eq(baseVo.getBaseId()));
        List<EnterpriseDepartment> enterpriseDepartments = queryFactory
                .select(qEnterpriseDepartment)
                .from(qEnterpriseDepartment)
                .where(booleanBuilder.getValue())
                .fetch();
        List<EnterpriseDepartmentDTO> recycleDTOS = CopyUtil.copyList(enterpriseDepartments, EnterpriseDepartmentDTO.class);
        return recycleDTOS;

    }

    public EnterpriseDepartmentDTO findByEnterpriseDepartmentId(long companyDepartmentId) {
        QEnterpriseDepartment qEnterpriseDepartment = QEnterpriseDepartment.enterpriseDepartment;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterpriseDepartment.id.eq(companyDepartmentId));
        EnterpriseDepartment enterpriseDepartment = queryFactory
                .select(qEnterpriseDepartment)
                .from(qEnterpriseDepartment)
                .where(booleanBuilder.getValue()).fetchOne();
        EnterpriseDepartmentDTO EnterpriseDepartmentDTO = CopyUtil.copyEnty(enterpriseDepartment, EnterpriseDepartmentDTO.class);
        return EnterpriseDepartmentDTO;

    }

    public EnterpriseDepartmentDTO existByCompanyDepartmentName(String enterpriseDepartmentName, long enterpriseDepartmentId) {
        QEnterpriseDepartment qEnterpriseDepartment = QEnterpriseDepartment.enterpriseDepartment;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterpriseDepartment.departmentName.eq(enterpriseDepartmentName));
        booleanBuilder.and(qEnterpriseDepartment.enterpriseId.eq(enterpriseDepartmentId));
        EnterpriseDepartment enterpriseDepartment = queryFactory
                .select(qEnterpriseDepartment)
                .from(qEnterpriseDepartment)
                .where(booleanBuilder.getValue()).fetchOne();
        EnterpriseDepartmentDTO EnterpriseDepartmentDTO = CopyUtil.copyEnty(enterpriseDepartment, EnterpriseDepartmentDTO.class);
        return EnterpriseDepartmentDTO;

    }


    public long departmentCount(PageEnty<EnterpriseDepartmentVO> departmentListPageEntyVO) throws Exception {
        QEnterpriseDepartment qEnterpriseDepartment = QEnterpriseDepartment.enterpriseDepartment;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        if (departmentListPageEntyVO.getVo() == null)
            throw new VerificationException(ReplRyCode.DATA_ERROR, ReplRyCode.DATA_ERROR.getMessage());
        EnterpriseDepartmentVO companyDepartmentVO = departmentListPageEntyVO.getVo();
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        long baseId = departmentListPageEntyVO.getBaseId() == 0 ? userId : departmentListPageEntyVO.getBaseId();
//        booleanBuilder.and(qCompany.baseId.eq(userId));
        if (companyDepartmentVO.getEnterpriseId() != 0) {
            booleanBuilder.and(qEnterpriseDepartment.enterpriseId.eq(companyDepartmentVO.getEnterpriseId()));
        } else if (!StringUtils.isEmpty(companyDepartmentVO.getEnterpriseName())) {
            booleanBuilder.and(qEnterpriseDepartment.departmentName.eq(companyDepartmentVO.getEnterpriseName()));
        } else {
            List<Long> Enterprises = Lists.newArrayList();
            enterpriseService.findByBaseId(baseId).stream().forEach(cd -> {
                Enterprises.add(cd.getId());
            });
            booleanBuilder.and(qEnterpriseDepartment.enterpriseId.in(Enterprises));
        }
        long count = queryFactory
                .select(qEnterpriseDepartment.count())
                .from(qEnterpriseDepartment)
                .where(booleanBuilder.getValue())
                .fetchCount();
        return count;
    }

    public List<EnterpriseDepartmentDTO> pageDepartmentList(PageEnty<EnterpriseDepartmentVO> departmentListPageEntyVO) throws Exception {
        QEnterpriseDepartment qEnterpriseDepartment = QEnterpriseDepartment.enterpriseDepartment;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        List<EnterpriseDepartmentDTO> companyDepartmentDTOS = Lists.newArrayList();
        if (departmentListPageEntyVO.getVo() == null)
            throw new VerificationException(ReplRyCode.DATA_ERROR, ReplRyCode.DATA_ERROR.getMessage());
        EnterpriseDepartmentVO companyDepartmentVO = departmentListPageEntyVO.getVo();
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        long baseId = departmentListPageEntyVO.getBaseId() == 0 ? userId : departmentListPageEntyVO.getBaseId();
//        booleanBuilder.and(qCompany.baseId.eq(userId));
        if (companyDepartmentVO.getEnterpriseId() != 0) {
            booleanBuilder.and(qEnterpriseDepartment.enterpriseId.eq(companyDepartmentVO.getEnterpriseId()));
        } else if (!StringUtils.isEmpty(companyDepartmentVO.getEnterpriseName())) {
            booleanBuilder.and(qEnterpriseDepartment.departmentName.like("%" + companyDepartmentVO.getEnterpriseName() + "%"));
        } else {
            List<Long> Enterprises = Lists.newArrayList();
            enterpriseService.findByBaseId(baseId).stream().forEach(cd -> {
                Enterprises.add(cd.getId());
            });
            booleanBuilder.and(qEnterpriseDepartment.enterpriseId.in(Enterprises));
        }
        List<EnterpriseDepartment> enterpriseDepartments = queryFactory
                .select(qEnterpriseDepartment)
                .from(qEnterpriseDepartment)
                .where(booleanBuilder.getValue())
                .offset((departmentListPageEntyVO.getPage() - 1) * departmentListPageEntyVO.getNum())
                .limit(departmentListPageEntyVO.getNum())
                .orderBy(qEnterpriseDepartment.createTime.desc())
                .fetch();
        enterpriseDepartments.stream().forEach(cd -> {
            EnterpriseDepartmentDTO companyDepartmentDTO = new EnterpriseDepartmentDTO();
            companyDepartmentDTO.setId(cd.getId());
            companyDepartmentDTO.setCreateTime(cd.getCreateTime());
            companyDepartmentDTO.setEnterpriseName(cd.getDepartmentName());
            EnterpriseDTO enterpriseDTO = enterpriseService.findByEnterpriseId(cd.getEnterpriseId());
            companyDepartmentDTO.setEnterpriseName(enterpriseDTO.getEnterpriseName());
            companyDepartmentDTOS.add(companyDepartmentDTO);
        });
        return companyDepartmentDTOS;

    }

    public List<EnterpriseDepartment> findByEnterpriseId(long enterpriseId) {
        QEnterpriseDepartment qEnterpriseDepartment = QEnterpriseDepartment.enterpriseDepartment;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qEnterpriseDepartment.enterpriseId.eq(enterpriseId));
        List<EnterpriseDepartment> enterpriseDepartments = queryFactory
                .select(qEnterpriseDepartment)
                .from(qEnterpriseDepartment)
                .where(booleanBuilder.getValue())
                .fetch();
        return enterpriseDepartments;

    }

}
